package com.authservice.authservice.util;

import com.authservice.authservice.domain.User;
import com.commonmodule.commonmodule.util.AESUtils;
import com.commonmodule.commonmodule.util.RedisUtil;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * @author zxb
 * @version 1.0
 * @date 2024-10-24 11:16
 */
@Component
public class TokenUtil {

    @Resource
    private RedisUtil redisUtil;

    // 加密密钥常量
    private final static String ENCRYPT_KEY = "xiangyu_test:";
    // 过期时间   毫秒   两个小时
    private final static Integer EXPIRE_TIME = 7200000;



    // 生成 token 要封装到 token 中的内容，如果需要传递多个值，那么可以定义为 Map 或者 JSON* @return 返画 token
    public String createToken(User user) {

        String token = UUID.randomUUID().toString();

        user.setToken(user.getPhone() + token);

        // 过期具体时间
        long l = System.currentTimeMillis();
        long expireTime = (long) (EXPIRE_TIME) + l;
        user.setExpireTime(String.valueOf(expireTime));
        String key = ENCRYPT_KEY + user.getPhone() + token;

        // 缓存数据
        redisUtil.save(key,user.toString(),EXPIRE_TIME,TimeUnit.MILLISECONDS);

        HashMap<String, Object> map = new HashMap<>();
        map.put("token", user.getPhone() + token);
        map.put("userName", user.getName());
        map.put("phone", user.getPhone());
        map.put("expireTime", expireTime);
        return AESUtils.getEncryptString(map.toString());

    }


    // 校验token
    public boolean verifyToken(String token) {
        try {
            // token解密
            String data = AESUtils.getDecryptString(token);
            // 获取数据
            JsonElement jsonElement = JsonParser.parseString(data);
            JsonObject obj = jsonElement.getAsJsonObject();
            String token1 = obj.get("token").getAsString();

            String key = ENCRYPT_KEY + token1;

            // 校验token是否存在
            if (redisUtil.verify(key)) {
                // token过期时间
                String expireTime = obj.get("expireTime").getAsString();
                long l = Long.parseLong(expireTime);
                // 当前时间戳
                long l1 = System.currentTimeMillis();

                // 如果过期时间小于 30000毫秒   则刷新过期时间
                if (l > l1 && (l - l1) < 30000L) {
                    long newExpireTime = (long) (EXPIRE_TIME * 1000) + l1;
                    obj.addProperty("expireTime", newExpireTime);
                    // 修改过期时间
                    redisUtil.save(key, obj.toString(),EXPIRE_TIME,TimeUnit.MILLISECONDS);
                }
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据token获取key
     * @param token
     * @return
     */
    public String getKey(String token){

        // token解密
        String data = AESUtils.getDecryptString(token);
        // 获取数据
        JsonElement jsonElement = JsonParser.parseString(data);
        JsonObject obj = jsonElement.getAsJsonObject();
        String token1 = obj.get("token").getAsString();
        String key = ENCRYPT_KEY + token1;

        return key;
    }


    /**
     * 校验手机号码格式
     * @param phoneNumber
     * @return
     */
    public boolean isValidPhoneNumber(String phoneNumber) {
        if ((phoneNumber != null) && (!phoneNumber.isEmpty())) {
            return Pattern.matches("^1[3-9]\\d{9}$", phoneNumber);
        }
        return false;
    }


    /**
     * 删除该账号的所有缓存
     * @param account
     */
    public void deleteKeys(String account){
        redisUtil.deleteKeys(ENCRYPT_KEY + account);
    }

}
